package com.pmcc.core.service;

import com.pmcc.core.config.security.JwtUser;
import com.pmcc.core.dto.EmployeeDTO;
import com.pmcc.core.entity.security.Employee;
import com.pmcc.core.entity.security.Organization;
import com.pmcc.core.entity.security.Role;
import com.pmcc.core.enums.EmpType;
import com.pmcc.core.enums.RoleType;
import com.pmcc.core.repository.EmployeeRepository;
import com.pmcc.core.repository.OrganizationRepository;
import com.pmcc.core.repository.RoleRepository;
import com.pmcc.core.vo.EmployeeVO;
import com.pmcc.utils.AntPage;
import com.pmcc.utils.BeanUtils;
import com.pmcc.utils.ResultBean;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * Created by syk on 17/8/4.
 */
@Service
@Transactional
public class EmployeeService {

    @Autowired
    EmployeeRepository employeeRepository;

    @Autowired
    OrganizationRepository organizationRepository;

    @Autowired
    RoleRepository roleRepository;

    /**
     * 查询列表
     *
     * @return
     */
    public ResultBean queryList(AntPage antPage, EmployeeDTO model) {
        ResultBean resultBean = new ResultBean();
        resultBean.setResultCode(ResultBean.SUCCESS);
        antPage.setSort("createTime");
        antPage.setOrder(AntPage.DESC);
        Page<Employee> employeePage = employeeRepository.findAll(this.getSpecification(model), antPage.getPageRequest());
        List<EmployeeVO> voList = new ArrayList<>();
        for (Employee obj : employeePage.getContent()) {
            EmployeeVO vo = new EmployeeVO();
            BeanUtils.copyProperties(obj, vo);
            vo.setOrgName(obj.getOrganization().getName());
            vo.setRoleName(obj.getRoleList().stream().map(Role::getName).collect(Collectors.joining(",")));
            voList.add(vo);
        }
        resultBean.setRows(voList);
        resultBean.setPage(antPage.getPage());
        resultBean.setPageSize(antPage.getPageSize());
        resultBean.setTotal(employeePage.getTotalElements());
        return resultBean;
    }


    /**
     * 关联查询
     *
     * @param model
     * @return
     */
    private Specification<Employee> getSpecification(EmployeeDTO model) {
        return (Root<Employee> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {

            List<Predicate> list = new ArrayList<Predicate>();
            // 姓名
            if (StringUtils.isNotEmpty(model.getUserCName())) {
                list.add(builder.like(root.get("userCName").as(String.class), "%" + model.getUserCName().trim() + "%"));
            }

            if (model.getType() != null) {
                list.add(builder.equal(root.get("type").as(EmpType.class), model.getType()));
            }

            if (StringUtils.isNotEmpty(model.getOrgId())) {
                list.add(builder.equal(root.get("organization").get("id").as(String.class), model.getOrgId()));
            }

            if (StringUtils.isNotEmpty(model.getCreateId())) {
                list.add(builder.equal(root.get("createId").as(String.class), model.getCreateId()));
            }

            list.add(builder.equal(root.get("delFlag").as(String.class), "0"));

            Predicate[] p = new Predicate[list.size()];

            return builder.and(list.toArray(p));
        };
    }

    /**
     * 重置密码
     *
     * @param model
     * @return
     */
    public ResultBean rePwdEmp(Employee model) {
        ResultBean resultBean = new ResultBean();
        resultBean.setResultCode(ResultBean.SUCCESS);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        Employee employee = employeeRepository.findOne(model.getId());
        employee.setPassword(encoder.encode("123456"));
        employeeRepository.save(employee);
        return resultBean;
    }

    /**
     * 保存
     *
     * @param model
     * @return
     */
    public ResultBean saveOrUpdate(EmployeeDTO model) {
        ResultBean resultBean = new ResultBean();
        Employee employee = employeeRepository.findByUsername(model.getUsername());
        JwtUser jwtUser = (JwtUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        if (StringUtils.isEmpty(model.getId())) {// 新增
            if (employee != null) {
                resultBean.setResultCode(ResultBean.FAIL);
                resultBean.setResultDesc("登录名已存在！");
                return resultBean;
            }

            Employee newModel = new Employee();
            BeanUtils.copyProperties(model, newModel);

            if (StringUtils.isEmpty(model.getOrgId())) {
                Organization org = organizationRepository.findOne("01");
                newModel.setOrganization(org);
            }

            newModel.setDelFlag("0");
            newModel.setCreateId(jwtUser.getId());
            newModel.setCreateName(jwtUser.getUserCName());
            newModel.setModifyId(jwtUser.getId());
            newModel.setModifyName(jwtUser.getUserCName());
            newModel.setPassword(encoder.encode(model.getPassword()));
            newModel.setLastLoginDate(new Date());
            employeeRepository.save(newModel);
            resultBean.setObject(newModel);
            resultBean.setResultDesc("新增成功");
        } else {
            if (employee != null && !employee.getId().equals(model.getId())) {
                resultBean.setResultCode(ResultBean.FAIL);
                resultBean.setResultDesc("登录名已存在！");
                return resultBean;
            }
            //修改保存
            Employee emp = employeeRepository.findOne(model.getId());
            BeanUtils.copyProperties(model, emp);
            employeeRepository.save(emp);
            resultBean.setObject(emp);
            resultBean.setResultDesc("修改成功");
        }
        resultBean.setResultCode(ResultBean.SUCCESS);
        return resultBean;
    }

    public ResultBean deleteEmp(Employee model) {
        ResultBean resultBean = new ResultBean(ResultBean.SUCCESS);
        try {
            employeeRepository.delete(model.getId());

        } catch (Exception e) {
            e.printStackTrace();
            resultBean.setResultCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    public ResultBean saveEmployeeRole(String userId, List<String> roles) {
        ResultBean resultBean = new ResultBean();
        Employee employee = employeeRepository.findOne(userId);
        employee.getRoleList().clear();

        List<Role> roleList = roles.stream().map(menuId -> roleRepository.findOne(menuId)).collect(Collectors.toList());
        for (Role obj : roleList) {
            obj.getEmployeeList().add(employee);
            employee.getRoleList().add(obj);
        }
        employeeRepository.save(employee);
        resultBean.setResultDesc("授权成功！");
        resultBean.setResultCode(ResultBean.SUCCESS);
        return resultBean;
    }

    /**
     * 主账号 保存 与修改
     *
     * @param model
     * @return
     */
    public ResultBean saveOrUpdateForMaster(EmployeeDTO model) {
        ResultBean resultBean = new ResultBean();
        Role role = roleRepository.findByType(RoleType.MASTER_ROLE);
        if (role == null) {
            resultBean.setResultCode(ResultBean.FAIL);
            resultBean.setResultDesc("主帐户角色不存在，请联系管理员！");
            return resultBean;
        }
        model.setType(EmpType.MASTER);
        resultBean = this.saveOrUpdate(model);
        if (StringUtils.isEmpty(model.getId())) {
            Employee temp = (Employee) resultBean.getObject();
            temp.getRoleList().add(role);
            role.getEmployeeList().add(temp);
        }

        return resultBean;
    }

    /**
     * 子账号 保存 与 修改
     *
     * @param model
     * @return
     */
    public ResultBean saveOrUpdateForSub(EmployeeDTO model) {
        ResultBean resultBean = new ResultBean();
        Role role = roleRepository.findByType(RoleType.SUB_ROLE);
        if (role == null) {
            resultBean.setResultCode(ResultBean.FAIL);
            resultBean.setResultDesc("子帐户角色不存在，请联系管理员！");
            return resultBean;
        }
        model.setType(EmpType.SUB);
        resultBean = this.saveOrUpdate(model);
        if (StringUtils.isEmpty(model.getId())) {
            Employee temp = (Employee) resultBean.getObject();
            temp.getRoleList().add(role);
            role.getEmployeeList().add(temp);
        }

        return resultBean;
    }
}
